import { app, shell, BrowserWindow, ipcMain, screen } from 'electron';
import { join } from 'path';
import { electronApp, optimizer, is } from '@electron-toolkit/utils';
import icon from '../../resources/icon.png?asset';
// 检查更新
import { autoUpdater } from 'electron-updater';

// 有些 API 只能在该事件发生后使用。
app.whenReady().then(() => {
    // 设置 Windows 系统的应用程序用户模型 ID
    electronApp.setAppUserModelId('com.electron');

    // 在开发模式下，默认通过 F12 打开或关闭开发者工具
    // 并在生产环境中忽略 CommandOrControl + R 快捷键
    // 参见 https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
    app.on('browser-window-created', (_, window) => {
        optimizer.watchWindowShortcuts(window); // 监听窗口快捷键
    });
    createMainWindow();

    //获取当前版本
    ipcMain.handle('app-version', () => {
        return app.getVersion();
    });
    ipcMain.handle('createWindow', (event, name, args) => {
        // console.log('🚀 ~ ipcMain.handle ~ event, name, width, height:', event, name, args);
        createWindow(name, args);
    });
    ipcMain.handle('deleteWindow', (event, name) => {
        deleteWindow(name);
    });
    ipcMain.handle('sendWindowMsg', (event, name, message, ...args) => {
        sendWindowMsg(name, message, ...args);
    });

    // 只有生产环境打包后才能测试更新
    if (!is.dev) {
        console.log('检查更新main');

        // 检查更新
        // ipcMain.on('update-check', (event, url) => {
        //     console.log('执行自动更新检查!!!', event, url);
        //     autoUpdater.checkForUpdates();
        //     handleUpdate(url);
        // });
    }

    app.on('activate', function () {
        // 在 macOS 上，通常当没有打开的窗口时，点击应用程序的 Dock 图标会重新创建一个窗口。
        if (BrowserWindow.getAllWindows().length === 0) {
            createMainWindow();
        }
    });
});
// 当所有窗口都关闭时退出，除非是 macOS 系统。对于 macOS，通常应用程序和菜单栏会保持活动状态，直到用户显式退出（Cmd + Q）。
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit(); // 退出应用程序
    }
});
// 忽略证书相关错误
// app.commandLine.appendSwitch('ignore-certificate-errors');
// 设置应用程序开机自启动
// app.setLoginItemSettings({
//     openAtLogin: true,
//     openAsHidden: false, // 设置为 true 可以隐藏启动时的窗口
//     args: [] // 自定义参数
// });

// 在此文件中，你可以包含应用程序的其他主进程特定代码。
// 你也可以将它们放在单独的文件中，并在这里引入它们。
// 创建主窗口
function createMainWindow(): void {
    // 创建窗口
    createWindow('main', { width: 960, height: 540 }, (browserWindow: BrowserWindow) => {
        if (is.dev) {
            browserWindow.webContents.openDevTools();
        }
        // browserWindow.setAlwaysOnTop(true, 'screen-saver');
        import('./ipcMain.js');
    });
}
// 创建窗口
interface WindowMap {
    [name: string]: BrowserWindow;
}

let windowMap: WindowMap = {}; // 存储窗口与别名的映射
// 创建窗口并指定别名
function createWindow(
    name: string,
    args: any = {},
    callback?: (browserWindow: BrowserWindow) => void
): void {
    console.log('🚀 ~ windowMap[name]:', windowMap[name]);
    if (windowMap[name]) {
        windowMap[name].focus(); // 如果窗口已经存在，聚焦它
        return;
    }

    // 获取屏幕大小
    let screenSize = screen.getPrimaryDisplay().size;
    // 如果没有传入宽度和高度，则使用默认值
    let finalWidth = args.width || Math.ceil((screenSize.width * 2) / 3); // 默认宽度为屏幕宽度的 2/3
    let finalHeight = args.height || Math.ceil((finalWidth * 9) / 16); // 默认高度按 16:9 比例计算

    const browserWindow = new BrowserWindow({
        show: false, // 窗口是否立即显示
        width: finalWidth, // 窗口宽度
        height: finalHeight, // 窗口高度
        minWidth: args.minWidth || finalWidth, // 窗口最小宽度
        minHeight: args.minHeight || finalHeight, // 窗口最小高度

        autoHideMenuBar: args.autoHideMenuBar ?? false, // 隐藏菜单栏
        fullscreen: args.fullscreen ?? is.dev ? false : true, // 是否可以全屏
        alwaysOnTop: args.alwaysOnTop ?? is.dev ? true : false, // 置顶
        frame: args.frame ?? true, // 是否显示边缘框
        hasShadow: args.hasShadow ?? false, // 是否显示阴影
        transparent: args.transparent ?? false, // 是否透明
        backgroundColor: args.backgroundColor ?? '#ffffff', // 背景色
        enableLargerThanScreen: args.enableLargerThanScreen ?? true, // 窗口是否可以大于屏幕
        icon: icon,
        webPreferences: {
            preload: join(__dirname, '../preload/index.js'), // 预加载的 js 文件内仍可以使用 Nodejs 的 API
            sandbox: false, // 是否启用沙盒模式，默认为 false
            devTools: true // 为 false 则禁止打开开发者工具
        }
    });

    // 将窗口与别名进行关联
    windowMap[name] = browserWindow;
    // 在窗口准备好显示时调用回调
    browserWindow.once('ready-to-show', () => {
        browserWindow.show(); // 显示窗口
        // 执行回调函数
        if (callback && typeof callback === 'function') {
            callback(browserWindow);
        }
        // 发送创建窗口成功消息
        setTimeout(() => {
            browserWindow.webContents.send('window-created', name);
        }, 1000);
    });
    browserWindow.webContents.setWindowOpenHandler((details) => {
        shell.openExternal(details.url);
        return { action: 'deny' };
    });

    // 监听窗口关闭事件，移除 windowMap 中的该窗口
    browserWindow.on('closed', () => {
        delete windowMap[name]; // 从 windowMap 中移除该窗口
        console.log(`窗口 "${name}" 已被关闭并从 windowMap 中删除`);
    });

    // 基于 electron-vite cli 实现热更新（HMR）。
    // 在开发环境加载远程 URL，生产环境加载本地 HTML 文件。
    let address = args.path || '';
    if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
        browserWindow.loadURL(`${process.env['ELECTRON_RENDERER_URL']}/#${address}`);
    } else {
        browserWindow.loadFile(join(__dirname, '../renderer/index.html'), {
            hash: address
        });
    }
}
// 通过别名获取窗口
function getWindow(name: string): BrowserWindow | null {
    return windowMap[name] || null;
}
// 删除指定别名的窗口
function deleteWindow(name: string): void {
    const windowToDelete = windowMap[name];
    if (windowToDelete) {
        windowToDelete.close(); // 关闭窗口
        delete windowMap[name]; // 从映射中删除该窗口
        console.log(`窗口 "${name}" 已被删除`);
    } else {
        console.log(`找不到名为 "${name}" 的窗口`);
    }
}

// 给指定窗口发送消息
function sendWindowMsg(name: string | string[], message: string, ...args: any[]): void {
    if (Array.isArray(name)) {
        // 如果是数组，则逐个发送消息
        name.forEach((name) => {
            const win = windowMap[name];
            if (win) {
                win.webContents.send(message, ...args); // 给该窗口发送消息
            }
        });
    } else {
        // 如果是单个别名，直接发送消息
        const win = windowMap[name];
        if (win) {
            win.webContents.send(message, ...args); // 给该窗口发送消息
        } else {
            console.log(`找不到名为 "${name}" 的窗口`);
        }
    }
}

// TAG应用更新
// 通过main进程发送事件给renderer进程，提示更新信息
function sendUpdateMessage(text: string | object) {
    let browserWindow = getWindow('main');
    console.log('sendUpdateMessage', text, browserWindow);

    if (browserWindow) {
        browserWindow.webContents.send('update-message', text);
    }
}
//处理更新操作
function handleUpdate(url: string) {
    // 检查更新
    // 设置是否自动下载，默认是true,当点击检测到新版本时，会自动下载安装包，所以设置为false
    // autoUpdater.autoDownload = false;
    (autoUpdater.autoInstallOnAppQuit = true), // 如果安装包下载好了，那么当应用退出后是否自动安装更新
        (autoUpdater.allowPrerelease = true), //  是否接受开发版，测试版之类的版本号
        (autoUpdater.allowDowngrade = true), //  是否可以回退版本，比如从开发版降到旧的稳定版
        // 自动检查更新
        autoUpdater.checkForUpdates();
    // 是否自动更新 不设置electron-updater 默认为true  手动触发更新要设置为false（没发现怎么用）
    // autoUpdater.autoDownload = false
    const returnData = {
        error: { status: -1, msg: '检测更新异常,请退出重试' },
        checking: { status: 0, msg: '正在检查应用程序更新...' },
        updateAva: { status: 1, msg: '检测到新版本，正在下载,请稍后...' },
        updateNotAva: {
            status: -1,
            msg: '您现在使用的版本为最新版本,无需更新!'
        },
        downloading: { status: 2, msg: '正在下载安装包...' },
        downloaded: { status: 3, msg: '下载完成，正在安装' }
    };
    console.log('处理更新操作', returnData, url);
    let browserWindow = getWindow('main');

    // autoUpdater.setFeedURL(import.meta.env.VUE_APP_BASE_API); //地址
    autoUpdater.setFeedURL(url);
    //检查中
    autoUpdater.on('checking-for-update', () => {
        sendUpdateMessage(returnData.checking);
    });
    //更新错误
    autoUpdater.on('error', function () {
        setTimeout(() => {
            sendUpdateMessage(returnData.error);
        }, 1000);
    });
    //发现新版本
    //当发现一个可用更新的时候，更新包下载会自动开始
    autoUpdater.on('update-available', () => {
        setTimeout(() => {
            sendUpdateMessage(returnData.updateAva);
        }, 1000);
    });
    //当前版本为最新版本
    autoUpdater.on('update-not-available', () => {
        setTimeout(() => {
            sendUpdateMessage(returnData.updateNotAva);
        }, 1000);
    });

    // 更新下载进度事件
    autoUpdater.on('download-progress', function (progressObj) {
        setTimeout(() => {
            sendUpdateMessage(returnData.downloading);
            if (browserWindow) {
                browserWindow.webContents.send('update-downloadProgress', progressObj);
            }
        }, 2000);
    });
    // 下载完成，等待更新
    autoUpdater.on(
        'update-downloaded',
        // (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) => {
        () => {
            setTimeout(() => {
                sendUpdateMessage(returnData.downloaded);
                autoUpdater.quitAndInstall();
            }, 1000);
            // ipcMain.on("update-quitAndInstall", () => {
            //     console.log("执行自动更新检查!!!");
            //     const options = {
            //         message: "应用更新",
            //         type: "info",
            //         buttons: ["确定", "取消"],
            //         defaultId: 0,
            //         title: "应用更新",
            //         detail: "发现有新版本，是否更新？",
            //         icon: "../static/icon_32x32.ico",
            //         cancelId: 1,
            //     };
            //     // 加上getCurrentWindow()成为模态窗不可以点击其他地方
            //     // const { dialog } = window.electronAPI.remote;

            //     dialog.showMessageBox( BrowserWindow.getFocusedWindow(), options)
            //         .then((returnVal) => {
            //             if (returnVal.response === 0) {
            //                 console.log("开始更新");
            //                 // ipcRenderer.send("quitAndInstall");
            //                 // .quitAndInstall(isSilent, isForceRunAfter) 退出应用并安装更新， isSilent 是否静默更新，isForceRunAfter更新完后是否立即运行
            //                 autoUpdater.quitAndInstall()
            //             } else {
            //                 return;
            //             }
            //         });
            // });
        }
    );
    //执行自动更新检查
    // autoUpdater.checkForUpdates();
}

